﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ServiceContractTests.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the <seealso cref="ServiceContractTest" /> type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Services.UnitTests
{
    using System;
    using System.Linq;
    using System.Reflection;
    using System.ServiceModel;
    using System.Text;

    using Hisaab.Services.Interfaces;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Defines the <seealso cref="UnitTests.ServiceContractTests"/> type.
    /// </summary>
    [TestClass]
    public class ServiceContractTests
    {
        /// <summary>
        /// Tests the service contracts assembly and searches for missing [ServiceContract] attributes.
        ///     Should reduce bugs a lot.
        /// </summary>
        [TestMethod, Timeout(10000)]
        public void ServiceContractTest()
        {
            var sb = new StringBuilder();
            var errorCount = 0;

            try
            {
                var assembly = Assembly.GetAssembly(typeof(IAccountService));

                foreach (var type in assembly.GetTypes())
                {
                    var dataContractAttribute = type.GetCustomAttributes(typeof(ServiceContractAttribute), true).FirstOrDefault();

                    if (dataContractAttribute == null)
                    {
                        errorCount++;
                        sb.AppendLine(string.Format("Missing [ServiceContract] attribute on Type {0}", type.Name));
                    }
                }
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }

            if (errorCount > 0)
            {
                Assert.Fail(sb.ToString());
            }
        }

        /// <summary>
        /// Tests the service contracts assembly and searches for missing [OperationContract] attributes.
        ///     Should reduce bugs a lot.
        /// </summary>
        [TestMethod, Timeout(10000)]
        public void OperationContractTest()
        {
            var sb = new StringBuilder();
            var errorCount = 0;

            try
            {
                var assembly = Assembly.GetAssembly(typeof(IAccountService));

                foreach (var type in assembly.GetTypes())
                {
                    var dataContractAttribute = type.GetCustomAttributes(typeof(ServiceContractAttribute), true).FirstOrDefault();

                    if (dataContractAttribute != null)
                    {
                        var methods = type.GetMethods();

                        foreach (var method in methods)
                        {
                            var dataMemberAttribute = method.GetCustomAttributes(typeof(OperationContractAttribute), true).FirstOrDefault();

                            if (dataMemberAttribute == null)
                            {
                                errorCount++;
                                sb.AppendLine(string.Format("Missing [OperationContract] attribute on Type {0}, Property {1}", type.Name, method.Name));
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }

            if (errorCount > 0)
            {
                Assert.Fail(sb.ToString());
            }
        }
    }
}